﻿namespace VisualPhysics.Scene.Core.Tests

open System
open System.Drawing
open VisualPhysics.Scene.Core
open VisualPhysics.Scene.Core.Operators
open VisualPhysics.Scene.Core.Tests.Utils
open NUnit.Framework
open FsUnit

type [<TestFixture>] ``BoxObject tests``() =
    
    [<Test>]
    [<Category("BoxObject.ValueMembers")>]
    member t.``Checking the Tag member of a BoxObject``() =
        let ``The box we are testing`` = BoxObject(pol (14.1<cm>, 31.41<cm>), 50.0<cm>, 150.0<cm>, 1.0<gram>)
        let ``The box we are testing as Object`` = ``The box we are testing``.Object()
        ``The box we are testing as Object``.Tag |> should equal Box

    [<Test>]
    [<Category("BoxObject.ValueMembers")>]
    member t.``Checking the Position member of a BoxObject``() =
        let ``The box we are testing`` = BoxObject(pol (14.1<cm>, 31.41<cm>), 50.0<cm>, 150.0<cm>, 1.0<gram>)
        let ``The box we are testing as Object`` = ``The box we are testing``.Object()
        ``The box we are testing as Object``.CarPosition
        |> equalTuples (14.1<cm>, 31.41<cm>)
        |> should equal (14.1<cm>, 31.41<cm>)

    [<Test>]
    [<Category("BoxObject.ValueMembers")>]
    member t.``Checking the Velocity member of a BoxObject``() =
        let ``The box we are testing`` = BoxObject(pol (14.1<cm>, 31.41<cm>), 50.0<cm>, 150.0<cm>, 1.0<gram>, velocity = (1.0<cm / s>, 2.0))
        let ``The box we are testing as Object`` = ``The box we are testing``.Object()
        ``The box we are testing as Object``.Velocity |> should equal (1.0<cm / s>, 2.0)

    [<Test>]
    [<Category("BoxObject.ValueMembers")>]
    member t.``Checking the Color member of a BoxObject``() =
        let ``The box we are testing`` = BoxObject(pol (14.1<cm>, 31.41<cm>), 50.0<cm>, 150.0<cm>, 1.0<gram>)
        let ``The box we are testing as Object`` = ``The box we are testing``.Object()
        ``The box we are testing as Object``.Color |> should equal Brushes.Black

    [<Test>]
    [<Category("BoxObject.ValueMembers")>]
    member t.``Checking the Mass member of a BoxObject``() =
        let ``The box we are testing`` = BoxObject(pol (14.1<cm>, 31.41<cm>), 50.0<cm>, 150.0<cm>, 1.0<gram>)
        let ``The box we are testing as Object`` = ``The box we are testing``.Object()
        ``The box we are testing as Object``.Mass |> should equal 1.0<gram>

    [<Test>]
    [<Category("BoxObject.ValueMembers")>]
    member t.``Checking the Points member of a BoxObject for the origin point``() =
        let ``The box we are testing`` = BoxObject(pol (14.1<cm>, 31.41<cm>), 50.0<cm>, 150.0<cm>, 1.0<gram>)
        ``The box we are testing``.Points
        |> List.exists ((equalTuples (14.1<cm>, 31.41<cm>)) >> (=) (14.1<cm>, 31.41<cm>))
        |> should be True

    [<Test>]
    [<Category("BoxObject.ValueMembers")>]
    member t.``Checking the Points member of a BoxObject for the correct length``() =
        let ``The box we are testing`` = BoxObject(pol (14.1<cm>, 31.41<cm>), 50.0<cm>, 150.0<cm>, 1.0<gram>)
        ``The box we are testing``.Points |> should haveLength 4

    [<Test>]
    [<Category("BoxObject.ValueMembers")>]
    member t.``Checking the Points member of a BoxObject when rotation is 0``() =
        let ``The box we are testing`` = BoxObject(pol (10.0<cm>, 20.0<cm>), 50.0<cm>, 150.0<cm>, 1.0<gram>)
        ``The box we are testing``.Points
        |> equalListTuples [(10.0<cm>, 20.0<cm>);(60.0<cm>, 20.0<cm>);(10.0<cm>, 170.0<cm>);(60.0<cm>, 170.0<cm>)]
        |> should equal [(10.0<cm>, 20.0<cm>);(60.0<cm>, 20.0<cm>);(10.0<cm>, 170.0<cm>);(60.0<cm>, 170.0<cm>)]

    [<Test>]
    [<Category("BoxObject.ValueMembers")>]
    member t.``Checking the Points member of a BoxObject when rotation is 30``() =
        let ``The box we are testing`` = BoxObject(pol (10.0<cm>, 20.0<cm>), 50.0<cm>, 150.0<cm>, 1.0<gram>, deg2rad 30.0<degree>)
        let ``Expected result`` = [
                            (10.0<cm>, 20.0<cm>);
                            (10.0<cm> + ((sqrt 3.0) * 50.0<cm> / 2.0), 20.0<cm> - (50.0<cm> / 2.0));
                            (10.0<cm> + (150.0<cm> / 2.0), 20.0<cm> + ((sqrt 3.0) * 150.0<cm> / 2.0));
                            (10.0<cm> + (150.0<cm> / 2.0) + ((sqrt 3.0) * 50.0<cm> / 2.0), 20.0<cm> - (50.0<cm> / 2.0) + ((sqrt 3.0) * 150.0<cm> / 2.0))]
        ``The box we are testing``.Points
        |> equalListTuples ``Expected result``
        |> should equal ``Expected result``

    [<Test>]
    [<Category("BoxObject.ValueMembers")>]
    member t.``Checking the Rotation member of a BoxObject``() =
        let ``The box we are testing`` = BoxObject(pol (10.0<cm>, 20.0<cm>), 50.0<cm>, 150.0<cm>, 1.0<gram>, Math.PI / 6.0)
        ``The box we are testing``.Rotation |> should equal (Math.PI / 6.0)

    [<Test>]
    [<Category("BoxObject.ValueMembers")>]
    member t.``Checking the Size member of a BoxObject for the origin point``() =
        let ``The box we are testing`` = BoxObject(pol (14.1<cm>, 31.41<cm>), 50.0<cm>, 150.0<cm>, 1.0<gram>)
        ``The box we are testing``.Size |> should equal (50.0<cm>, 150.0<cm>)

    [<Test>]
    [<Category("BoxObject.Setters")>]
    member t.``Changing the position of a BoxObject as Object``() =
        let ``The box we are testing`` = BoxObject(pol (14.1<cm>, 31.41<cm>), 50.0<cm>, 150.0<cm>, 1.0<gram>)
        let ``The box we are testing as Object`` = ``The box we are testing``.Object()
        let ``The new box`` = ``The box we are testing as Object``.SetCarPosition (4.0<cm>, 6.0<cm>)
        ``The new box``.CarPosition |> should equal (4.0<cm>, 6.0<cm>)

    [<Test>]
    [<Category("BoxObject.Setters")>]
    member t.``Changing the color of a BoxObject as Object``() =
        let ``The box we are testing`` = BoxObject(pol (14.1<cm>, 31.41<cm>), 50.0<cm>, 150.0<cm>, 1.0<gram>)
        let ``The box we are testing as Object`` = ``The box we are testing``.Object()
        let ``The new box`` = ``The box we are testing as Object``.SetColor Brushes.Orange
        ``The new box``.Color |> should equal Brushes.Orange